import hmac
import hashlib
import base64
import json
import urllib
import random
import time
from typing import Dict, Any, Optional
from hashlib import sha256

import requests


class SignatureGenerator:
    """Bugly OpenAPI签名生成器"""

    VERSION = "202100"
    SIGN_METHOD = "HmacSHA256"
    MIN_NONCE = 100000

    def __init__(self, api_id: str, api_key: str):
        """
        初始化签名生成器

        Args:
            api_id: API ID，用于身份识别
            api_key: API Key，用于接口身份校验
        """
        self.api_id = api_id
        self.api_key = api_key

    def _hmac_sha256(self, message: str, key: str) -> bytes:
        """使用HmacSHA256算法生成签名"""
        key_bytes = key.encode('utf-8')
        message_bytes = message.encode('utf-8')

        hmac_obj = hmac.new(key_bytes, message_bytes, hashlib.sha256)
        return hmac_obj.digest()

    def generate_hashed_payload(self, body: str) -> str:
        """生成请求包体的签名"""
        # 1. HmacSHA256签名
        sha = self._hmac_sha256(body, self.api_key)

        # 2. Base64编码
        base64_str = base64.b64encode(sha).decode('utf-8')

        # 3. URL编码
        return urllib.parse.quote(base64_str)

    def _generate_sign_str(self, hashed_payload: Optional[str] = None) -> str:
        """生成待签名字符串"""
        # 准备签名参数
        params: Dict[str, str] = {
            'apiID': self.api_id,
            'nonce': str(random.randint(self.MIN_NONCE, 99999)),
            'signMethod': self.SIGN_METHOD,
            'timestamp': str(int(time.time())),
            'version': self.VERSION
        }

        # 如果有包体签名，添加到参数中
        if hashed_payload:
            params['hashedPayload'] = hashed_payload

        # 按字典序排序并拼接参数
        sorted_params = sorted(params.items(), key=lambda x: x[0])
        return '&'.join(f"{k}={v}" for k, v in sorted_params)

    def generate_authorization(self, body: Optional[str] = None) -> str:
        """生成完整的Authorization header值"""
        # 如果有body，先生成包体签名
        hashed_payload = self.generate_hashed_payload(body) if body else None

        # 生成待签名字符串
        sign_str = self._generate_sign_str(hashed_payload)

        # 生成签名
        sha = self._hmac_sha256(sign_str, self.api_key)

        # Base64编码
        signature = urllib.parse.quote(
            base64.b64encode(sha).decode('utf-8')
        )

        # 拼接最终的授权字符串
        return f"{sign_str}&signature={signature}"

    def computeHmacSha256(self,message,secret):
        secrets = secret.encode('utf-8')
        message = message.encode('utf-8')
        # hamcSha256加密成16进制的字符串
        sha = hmac.new(secrets, message, digestmod=sha256).hexdigest()
        # base64编码
        sign = base64.b64encode(str.encode(sha))
        sign = str(sign, 'utf-8')
        url_str = urllib.parse.quote(sign)
        return url_str


    def GetAuthorization(self,body):
        appID = self.api_id
        appKey = self.api_key
        nonce = random.randint(100000,9999999)
        timestamp = int(time.time())
        if len(body) > 0:
            hashedPayload = self.computeHmacSha256(body,appKey)
            sign = "apiID={}&hashedPayload={}&nonce={}&signMethod={}&timestamp={}&version={}".format(
                appID,hashedPayload,nonce,self.SIGN_METHOD,timestamp,self.VERSION
            )
        else:
            sign = "apiID={}&nonce={}&signMethod={}&timestamp={}&version={}".format(
                appID, nonce, self.SIGN_METHOD, timestamp, self.VERSION
            )
        signature = self.computeHmacSha256(sign,appKey)
        #print("signature is:{}".format(signature))
        return sign + "&signature={}".format(signature)

class BuglyOpenAPI:
    def __init__(self, secret_id: str, secret_key: str):
        self.api_domain = "https://api.bugly.tds.qq.com"
        self.secret_id = secret_id
        self.secret_key = secret_key
        self.signature_generator = SignatureGenerator(secret_id, secret_key)

    def get_v1_version(self,product_id: str,product_key: str) -> str:
        headers = {
            'Content-Type': 'application/json',
            'X-ProductId': product_id,
            'X-ProductKey': product_key,
        }

        data = {
            "product_id": product_id,
            "biz_type": "crash",
            "start_time": "2025-07-07T00:00:00+08:00",
            "end_time": "2025-07-13T00:00:00+08:00",
            "platform": "Android"
        }

        body_str = json.dumps(data)

        if body_str:
            headers['Authorization'] = self.signature_generator.GetAuthorization(body_str)

        response = requests.post(self.api_domain + "/v1/sum/version",
                                 headers=headers,
                                 data=body_str)
        return response.json()

if __name__ == '__main__':
    bugly_openapi = BuglyOpenAPI("buglypro_api_id_zuoyebang", "dbaa09e4-3c6f-48ea-9176-801638a64de4")
    res = bugly_openapi.get_v1_version("b99545917b","c31a736c-2e7f-4cf3-b90d-5a5d57c1b779")
    print(res)